package com.onpositive.units;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

import org.w3c.dom.Element;

import com.onpositive.knowledge.model.values.IHasValue;

public class ParsedScalar extends RangeValue<Double> implements Comparable<ParsedScalar>{

	/**
	 * 
	 */
	private static final long serialVersionUID = 2368090834063409275L;

	public static final String ID = "scalar" ;
	
	public ParsedScalar( Double doubleValue, String comment) {
		super(comment, doubleValue) ;
	}
	
	public ParsedScalar( Double lValue, Double uValue, String comment) {
		super(comment,lValue, uValue) ;
	}
	
	public ParsedScalar( ParsedValue pv, String comment ){
		super( pv,comment ) ;				
	}
	
	public ParsedScalar( Element element ) {
		super(element) ;
	}
	
	protected ParsedScalar(ParsedScalar other, Object value, String comment) {
		super( other, value, comment ) ;		
	}

	@Override
	public String getValueAsString() {
		
		StringBuilder bld = new StringBuilder() ;
		if( isRange() ){
			bld.append( NumberFormat.getInstance( Locale.US ).format(lowerBound) ) ;
			bld.append( getDefaultRangeDelimeter() ) ;
		}
		
		bld.append( NumberFormat.getInstance( Locale.US ).format(upperBound_def) ) ;
		
		final String result = bld.toString();
		return result ;
	}

	@Override
	@SuppressWarnings("unchecked")	
	public <S> S[] getConvertedValue( Class<S> clazz )
	{
		if( clazz == Double.class ){
			if( isRange() ){
				return (S[]) new Double[]{ getLowerBound() , getUpperBound() } ;
			}
			else
				return (S[]) new Double[]{ getUpperBound() } ;
		}

		return null;
	}

	@Override
	public Class<Double> getValueClass() {
		return Double.class;
	}

	@Override
	public IHasValue clone(Object value, String comment) {
		
		if( comment == null )
			comment = this.getComment() ;
		
		if( value instanceof Double[] || value instanceof Double )
			return new ParsedScalar( this, value, comment );
		
		if(! (value instanceof double[]) )
			return null;
		
		double[] srcArr = (double[]) value ;
		int l = srcArr.length ;
		Double[] valArr = new Double[l] ;
		for( int i = 0 ; i < l ; i++ )
			valArr[i] = srcArr[i] ;
		
		return new ParsedScalar( this, valArr, comment );
	}
	
	@Override
	protected boolean valueIsStoredInSingleString(){ return true; }
	
	@Override
	protected void writeSingleValue(Element valNode, Double val){}
	@Override
	protected Double readSingleValue(Element n) {
		return null;
	}

	@Override
	protected Double readValue( String str ) {
		Number num;
		try {
			num = NumberFormat.getInstance( Locale.US ).parse( str );
			return num.doubleValue() ;
		} catch (ParseException e) {
			e.printStackTrace();
			return null ;
		}		
	}

	@Override
	protected String writeSingleValue(Double val) {
		return	NumberFormat.getInstance( Locale.US ).format( val );
	}

	@Override
	public Object describer() {
		return Double.class;
	}

	@Override
	public String getId() {
		return ID;
	}
	
	@Override
	public int compareTo(ParsedScalar other) {
		
		if(other==null)
			return 1;
		
		Double lb1 = this.getLowerBound();
		Double ub1 = this.getUpperBound();
		Double val1 = lb1 != null ? lb1 : ub1;
		
		Double lb2 = other.getLowerBound();
		Double ub2 = other.getUpperBound();
		Double val2 = lb2 != null ? lb2 : ub2;
		
		if(val1-val2 > 0 )
			return 1;
		
		return -1;
	}

		
}
